/**
 * 
 */
package com.huniu.links.colony;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import com.huniu.links.exception.LinkProcessException;
import com.huniu.links.model.LinkXMLProperty;
import com.huniu.links.model.ModelXMLProperty;
import com.huniu.links.model.SeedXMLProperty;
import com.huniu.utility.DateUtil;

/**
 * @author zandy (chenheng)
 * 
 */
public class ScoutBeeBehaviorImpl extends AbstractBeeBehaviorImpl implements IScoutBeeBehavior {

	private static Logger logger = Logger.getLogger(ScoutBeeBehaviorImpl.class);

	private File seedFile;
	private String linkFolder;

	public void setSeedFile(File seedFile) {
		this.seedFile = seedFile;
	}

	public void setLinkFolder(String linkFolder) {
		this.linkFolder = linkFolder;
	}

	private String fetchHtmlResource(String url) throws LinkProcessException {
		try {
			HttpURLConnection connection = (HttpURLConnection) new URL(url)
					.openConnection();
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					connection.getInputStream()));
			String content = null;
			String line = null;
			while ((line = reader.readLine()) != null) {
				content += line;
			}
			reader.close();
			return content;
		} catch (MalformedURLException e) {
			throw new LinkProcessException(
					"Unable to open connection. Malformation URL :" + url, e);
		} catch (IOException e) {
			throw new LinkProcessException(
					"Unable to open connection. IO error : " + url, e);
		}
	}

	private boolean processUrl(String url) {
		try {
			logger
					.info("=============================>>>> Scout Bee begin to search resource");
			String content = fetchHtmlResource(url);
			logger.info("Fetch html resource successful :" + url);
			CacheManager singletonManager = CacheManager.create();
			logger.info("Get singleton cache manager : "
					+ singletonManager.getName());
			Cache cache = singletonManager.getCache(LINK_PAGE_CACHE_NAME);
			logger.info("Get cache object : " + cache.getName());
			Element element = new Element(url, content);
			cache.put(element);
			logger.info("Put emement({key=" + element.getKey()
					+ ",value=...}) to cache : " + cache.getName());
			logger
					.info("<<<<============================= Scout Bee finish to search resource");
			return true;
		} catch (LinkProcessException e) {
			logger.error(e.getMessage(), e);
			logger
					.error("<<<<============================= Scout Bee fail to search resource");
			return false;
		}
	}

	private void generateLinkFile(Document document)
			throws LinkProcessException {
		String fileName = DateUtil.convertDateToString(new Date(),
				DateUtil.DATE_FORMAT_2);
		String filePath = this.linkFolder + File.separator + fileName + LinkXMLProperty.EXTENSION;
		try {
			OutputFormat format = OutputFormat.createPrettyPrint();
			XMLWriter writer = new XMLWriter(
					new FileWriter(new File(filePath)), format);
			writer.write(document);
			writer.close();
		} catch (IOException e) {
			throw new LinkProcessException("Write XML document failure", e);
		}
	}

	public void process() {
		if (this.seedFile != null) {
			Document linkDocument = DocumentHelper.createDocument();
			org.dom4j.Element root = linkDocument.addElement(LinkXMLProperty.ROOT);
			Document document;
			try {
				document = parseXMLFile(seedFile);
				List<String> urlList = parseLinks(document,SeedXMLProperty.ELEMENT);
				for (String url : urlList) {
					if (processUrl(url)) {
						root.addElement(LinkXMLProperty.ELEMENT).addText(url);
					}
				}
				generateLinkFile(linkDocument);
			} catch (DocumentException e) {
				logger.error(e.getMessage(), e);
			} catch (LinkProcessException e) {
				logger.error(e.getMessage(), e);
			}
		}
	}

	public void run() {
		process();
	}

}
